home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / X11R4 / cmds / X / os / sprite.X11R3 / scheduler.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-06-01  |  8.6 KB  |  309 lines

  1. /*-
  2.  * scheduler.c --
  3.  *    OS dependent scheduling routines:
  4.  *    WaitForSomething, SchedPacket, SchedYield
  5.  *
  6.  * Copyright (c) 1987 by the Regents of the University of California
  7.  *
  8.  * Permission to use, copy, modify, and distribute this
  9.  * software and its documentation for any purpose and without
  10.  * fee is hereby granted, provided that the above copyright
  11.  * notice appear in all copies.  The University of California
  12.  * makes no representations about the suitability of this
  13.  * software for any purpose.  It is provided "as is" without
  14.  * express or implied warranty.
  15.  *
  16.  *
  17.  */
  18. #ifndef lint
  19. static char rcsid[] =
  20.     "$Header: /a/X/src/cmds/Xsprite/os/RCS/scheduler.c,v 1.11 89/06/01 10:44:49 brent Exp $ SPRITE (Berkeley)";
  21. #endif lint
  22.  
  23. #include    "spriteos.h"
  24. #include    <bit.h>
  25. #include    <errno.h>
  26. #include    <sys/time.h>
  27.  
  28. #include    "dixstruct.h"
  29. #include    "opaque.h"
  30.  
  31. #include    "misc.h"
  32.  
  33. extern long ScreenSaverTime;            /* milliseconds */
  34. extern long ScreenSaverInterval;        /* milliseconds */
  35.  
  36. Bool isItTimeToYield = TRUE;
  37.  
  38. /*-
  39.  *-----------------------------------------------------------------------
  40.  * WaitForSomething --
  41.  *    Hang out until something interesting happens:
  42.  *        - data from clients
  43.  *        - new client connecting
  44.  *        - device input available
  45.  *    If no input events come in for a sufficiently long time
  46.  *    (ScreenSaverTime), turns on the screen saver.
  47.  *
  48.  *         For more info on ClientsWithInput, see ReadRequestFromClient().
  49.  *         pClientsReady is a mask, the bits set are 
  50.  *         indices into the o.s. depedent table of available clients.
  51.  *         (In this case, there is no table -- the index is the socket
  52.  *         file descriptor.)  
  53.  *
  54.  * Results:
  55.  *
  56.  * Side Effects:
  57.  *
  58.  *-----------------------------------------------------------------------
  59.  */
  60.  
  61. static int intervalCount = 0;
  62.  
  63. WaitForSomething(pClientsReady, pNumReady, pNewClients, pNumNew)
  64.     ClientPtr        *pClientsReady;     /* OUT: ready clients */
  65.     int           *pNumReady;            /* OUT: number of ready clients */
  66.     ClientPtr        *pNewClients;       /* OUT: new client pointers */
  67.     int           *pNumNew;            /* OUT: number of new clients */
  68. {
  69.     int            i;
  70.     struct timeval    waittime, *wt;
  71.     long        timeout;
  72.     
  73.     *pNumReady = 0;
  74.     *pNumNew = 0;
  75.  
  76.     if (!Bit_AnySet (NumActiveStreams, ClientsWithInputMask)) {
  77.     /*
  78.      * We need a while loop here to handle the screen saver timeout
  79.      */
  80.     while (1) {
  81.         if (clientsDoomed) {
  82.         Bit_Zero (NumActiveStreams, LastSelectMask);
  83.         break;
  84.         }
  85.         
  86.             if (ScreenSaverTime) {
  87.         /*
  88.          * If screen saver is needed, set 'timeout' to the time
  89.          * remaining until the screen saver should be activated.
  90.          */
  91.                 timeout = ScreenSaverTime - TimeSinceLastInputEvent();
  92.             if (timeout < 0) {
  93.             /*
  94.              * There is no time left -- activate the screen saver.
  95.              */
  96.                 if (timeout < intervalCount) {
  97.                 SaveScreens(SCREEN_SAVER_ON, ScreenSaverActive);
  98.                 if (intervalCount)
  99.                         intervalCount -= ScreenSaverInterval;
  100.                         else
  101.                             intervalCount = 
  102.                 -(ScreenSaverInterval + ScreenSaverTime);
  103.             }
  104.                     timeout -= intervalCount;
  105.                 } else {
  106.                 intervalCount = 0;
  107.         }
  108.                 waittime.tv_sec = timeout / 1000;
  109.             waittime.tv_usec = 0;
  110.         wt = &waittime;
  111.         } else {
  112.                 wt = (struct timeval *) NULL;
  113.         }
  114.  
  115.         Bit_Copy (NumActiveStreams, AllStreamsMask, LastSelectMask);
  116.  
  117.         BlockHandler(&wt, LastSelectMask);
  118.         i = select(NumActiveStreams, LastSelectMask, (int *) NULL,
  119.             (int *) NULL, wt);
  120.         if (i <= 0) {
  121.         if ((i == -1) && ((errno == EINVAL) || (errno == EIO))) {
  122.             /*
  123.              * If a stream was invalid, find each one that's
  124.              * bogus and close the client down. If it's one
  125.              * of the listening streams (Pdev_Conn, TCP_Conn,
  126.              * or NewPdev_Conn), close that down and set the
  127.              * appropriate variable to be -1 so we don't
  128.              * pay attention to it any more.
  129.              */
  130.             int                 *selMask;
  131.             struct timeval             poll;
  132.             register ClntPrivPtr    pPriv;
  133.             register ClientPtr        client;
  134.             int                junk;
  135.             
  136.             ErrorF("Bad stream in select -- seek and destroy...");
  137.             poll.tv_sec = 0;
  138.             poll.tv_usec = 0;
  139.             
  140.             Bit_Alloc(NumActiveStreams, selMask);
  141.             
  142.             for (i = 1; i < currentMaxClients; i++) {
  143.             client = clients[i];
  144.             pPriv = (ClntPrivPtr) ((client && !client->clientGone) ?
  145.                         client->osPrivate : 0);
  146.  
  147.             if (pPriv && (pPriv->ready != (int *)0)) {
  148.                 Bit_Copy(pPriv->maskWidth, pPriv->ready,
  149.                      selMask);
  150.                 junk = select(pPriv->maskWidth, selMask,
  151.                     (int *) NULL, (int *) NULL, &poll);
  152.                 if ((junk == -1) && ((errno == EINVAL)
  153.                     || (errno == EIO))) {
  154.                 ErrorF("CLIENT(%d) ", client->index);
  155.                 CloseDownClient(client);
  156.                 break;
  157.                 }
  158.             }
  159.             }
  160.             Bit_Zero(NumActiveStreams, selMask);
  161.             Bit_Set(Pdev_Conn, selMask);
  162.             junk = select(Pdev_Conn + 1, selMask, (int *) NULL,
  163.                 (int *) NULL, &poll);
  164.             if ((junk == -1) && ((errno == EINVAL) || (errno == EIO))) {
  165.             ErrorF("PDEV ");
  166.             (void)close(Pdev_Conn);
  167.             Bit_Clear(Pdev_Conn, selMask);
  168.             Bit_Clear(Pdev_Conn, AllStreamsMask);
  169.             Pdev_Conn = -1;
  170.             } else {
  171.             Bit_Clear(Pdev_Conn, selMask);
  172.             }
  173. #ifdef TCPCONN
  174.             Bit_Set(TCP_Conn, selMask);
  175.             junk = select(TCP_Conn + 1, selMask, (int *) NULL,
  176.                 (int *) NULL, &poll);
  177.             if ((junk == -1) && ((errno == EINVAL) || (errno == EIO))) {
  178.             ErrorF("TCP ");
  179.             (void)close(TCP_Conn);
  180.             Bit_Clear(TCP_Conn, selMask);
  181.             Bit_Clear(TCP_Conn, AllStreamsMask);
  182.             TCP_Conn = -1;
  183.             } else {
  184.             Bit_Clear(TCP_Conn, selMask);
  185.             }
  186. #endif /* TCPCONN */
  187.             ErrorF("done\n");
  188.         } else if (i != 0) {
  189.             Error("Scheduler Select");
  190.         }
  191.         i = 0;
  192.         Bit_Zero(NumActiveStreams, LastSelectMask);
  193.         }
  194.         WakeupHandler (&i, LastSelectMask);
  195.  
  196.         if (i > 0) {
  197.         if ((Pdev_Conn >= 0) && Bit_IsSet (Pdev_Conn, LastSelectMask)) {
  198.             Pdev_EstablishNewConnections (pNewClients, pNumNew);
  199.         }
  200. #ifdef TCPCONN
  201.         if ((TCP_Conn >= 0) && Bit_IsSet (TCP_Conn, LastSelectMask)) {
  202.             TCP_EstablishNewConnections (pNewClients, pNumNew);
  203.         }
  204. #endif TCPCONN
  205.  
  206.         if (*pNumNew ||
  207.             Bit_Intersect (NumActiveStreams, LastSelectMask,
  208.                    EnabledDevicesMask, (int *)NULL) ||
  209.             Bit_Intersect (NumActiveStreams, LastSelectMask,
  210.                    AllClientsMask, (int *)NULL)) {
  211.                       /*
  212.                        * If there are new connections, or
  213.                        * an enabled device has data available,
  214.                        * or there are requests from clients,
  215.                        * break out of this loop...we're ready
  216.                        * to return.
  217.                        */
  218.                       break;
  219.         }
  220.         }
  221.     }
  222.     } else {
  223.     register int i;
  224.     Bit_Copy (NumActiveStreams, ClientsWithInputMask, LastSelectMask);
  225.     Bit_Zero (NumActiveStreams, ClientsWithInputMask);
  226.     }
  227.     
  228.     if (Bit_Intersect(NumActiveStreams, LastSelectMask, AllClientsMask, NULL)){
  229.     /*
  230.      * If any clients are ready, go through the table of clients
  231.      * and see if any of the client's streams has its bit set in the
  232.      * select mask. Any that does has its bit set in the client's
  233.      * "ready" mask.
  234.      */
  235.     register ClntPrivPtr      pPriv;
  236.     register ClientPtr      client;
  237.  
  238.     for (i = 1; i < currentMaxClients; i++) {
  239.         client = clients[i];
  240.         pPriv = (ClntPrivPtr) ((client && !client->clientGone) ?
  241.                     client->osPrivate : 0);
  242.  
  243.         if (pPriv && (pPriv->ready != (int *)0) &&
  244.         Bit_Intersect (pPriv->maskWidth, LastSelectMask,
  245.                    pPriv->mask, pPriv->ready)) {
  246.                    pClientsReady[*pNumReady] = client;
  247.                    (*pNumReady)++;
  248.         }
  249.     }
  250.     }
  251.  
  252.     /*
  253.      * As a concession to the DDX layer, if any of the streams to devices
  254.      * is ready, call spriteInputAvail() to inform DDX of this.
  255.      */
  256.     if (Bit_Intersect (NumActiveStreams, LastSelectMask, EnabledDevicesMask,
  257.                NULL)) {
  258.                spriteInputAvail();
  259.     }
  260. }
  261.  
  262. static int      packets = 0;
  263. /*-
  264.  *-----------------------------------------------------------------------
  265.  * SchedPacket --
  266.  *    Record having received another packet for the given client.
  267.  *
  268.  * Results:
  269.  *    None.
  270.  *
  271.  * Side Effects:
  272.  *    ???
  273.  *
  274.  *-----------------------------------------------------------------------
  275.  */
  276. /*ARGSUSED*/
  277. void
  278. SchedPacket (client)
  279.     ClientPtr      client;
  280. {
  281.     if (!isItTimeToYield) {
  282.     packets += 1;
  283.     if (packets == MAX_PACKETS) {
  284.         isItTimeToYield = TRUE;
  285.         packets = 0;
  286.     }
  287.     }
  288. }
  289.  
  290. /*-
  291.  *-----------------------------------------------------------------------
  292.  * SchedYield --
  293.  *    Yield the server to another client.
  294.  *
  295.  * Results:
  296.  *    None.
  297.  *
  298.  * Side Effects:
  299.  *    isItTimeToYield is set TRUE.
  300.  *
  301.  *-----------------------------------------------------------------------
  302.  */
  303. void
  304. SchedYield()
  305. {
  306.     isItTimeToYield = TRUE;
  307.     packets = 0;
  308. }
  309.